package string;
/**
 * String常量池，是JVM在堆中开辟的一块空间，用于缓存所有通过字面量形式创建的字符串
 * 对象，那么当我们再使用已缓存的字面量创建字符串对象时就会重用该对象。
 * 这样可以减少内存开销。
 * @author 范传奇
 *
 */
public class StringDemo {
	public static void main(String[] args) {
		String s1 = "123abc";
		String s2 = "123abc";//s2重用了s1创建的对象
		//s1和s2都是引用类型变量，保存的是对象的地址，如果相同说明指向同一个对象
		System.out.println("s1==s2:" + (s1==s2));
		
		String s3 = "123abc";
		System.out.println("s2==s3:" + (s2==s3));//true
		//new关键字创建时一定产生新对象,java不推荐这种形式创建字符串。
		String s4 = new String("123abc");
		System.out.println("s4:"+s4);
		//new出来的字符串不会重用对象
		System.out.println("s2==s4:" + (s2==s4));//false
		
		/*
		 * String是不变对象，即:
		 * String对象创建后内容不可改变，若改变内容一定创建新对象
		 */
		System.out.println("s1:"+s1);
		s1 = s1 + "!";//修改内容就会创建新对象
		System.out.println("s1:"+s1);
		System.out.println("s2:"+s2);
		//s1已经不再与s2,s3指向同一个对象了
		System.out.println("s1==s2:" + (s1==s2));//false
		
		/*
		 * 触发了编译器的一个特性:
		 * 编译器在编译期间，如果发现一个计算表达式可以在编译期间确定结果时，就会
		 * 进行计算，并将计算结果编译到class文件中。
		 * 编译后的class文件中，下面的代码改为:
		 * String s5 = "123abc";
		 */
		String s5 = "123" + "abc";
		System.out.println("s5:"+s5);
		System.out.println("s2==s5:"+(s2==s5));//true
		
		String s = "123";
		String s6 = s + "abc";//修改内容会创建新对象
		System.out.println("s6:"+s6);
		System.out.println("s2==s6:"+(s2==s6));//false
		
		
	}
}









